package com.hp.tiger.chapter2;

import java.util.concurrent.TimeUnit;

/**
 * @author XavierDong
 **/
public class WaitSet {


    private static final Object LOCK = new Object();

    private static void work() {
        synchronized (LOCK) {
            System.out.println("Begin....");
            try {
                System.out.println("Thread will coming.");
                LOCK.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Thread will out.");
        }
    }


    /**
     * 1.所有对象都有一个wait set,用来存放调用了该对象wait方法之后进入 block状态的线程
     * 2.线程被notify之后，不一定立即得到执行
     * 3.线程从 wait set中被唤醒的顺序 不一定是 FIFO.
     * 4.线程会唤醒后，必须重新获取锁。会记录原先的执行位置，从原来的位置继续往后执行。。。。。
     */
    public static void main(String[] args) {

        new Thread(){
            @Override
            public void run() {
                work();
            }
        }.start();
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        synchronized (LOCK) {
            LOCK.notify();
        }

       /* IntStream.rangeClosed(1, 10).forEach(i ->
                new Thread(String.valueOf(i)) {
                    @Override
                    public void run() {
                        synchronized (LOCK) {
                            try {
                                Optional.of(Thread.currentThread().getName() + " will come to wait set.").ifPresent(System.out::println);
                                *//**
         * Thread线程放入 LOCK 的 WaitSet 中
         * blocked状态
         * *//*
                                LOCK.wait();
                                Optional.of(Thread.currentThread().getName() + " will leave to wait set.").ifPresent(System.out::println);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }.start()
        );

        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        IntStream.rangeClosed(1, 10).forEach(i -> {
                    synchronized (LOCK) {
                        LOCK.notify();
                        try {
                            TimeUnit.SECONDS.sleep(1);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }

        );*/


    }
}
